<html>
    <head>
        <title>createElement参数</title>
    </head>
    <body>
        <script>
             // 三、createElement 参数
                         
                            /*
                                接下来你需要熟悉的是如何在 createElement 函数中使用模板中的那些功能。

                                下面是 createElement 接受的参数：
                            */
                                    // @returns {VNode}
                                    createElement(
                                        // {String | Object | Function}
                                        // 一个HMTL标签名、组件选项对象，或者 resolve 了上述任何一种的async 函数。  必填项
                                        'div',

                                        // {object}
                                        // 一个与模板中 attribute 对应的数据对象。  可选项
                                        {
                                            // （详见下一节）
                                        },

                                        // 子级虚拟节点(VNodes)
                                        // {string | Array}
                                        // 子级虚拟节点(VNode),由 'createElement()'构建而成
                                        // 也可以使用字符串来生成"文本信息节点"   可选项
                                        [
                                            '先写一些文字',
                                            createElement('h1','一则头条'),
                                            createElement(MyComponent,{
                                                props:{
                                                    someProp:'foobar'
                                                }
                                            })
                                        ]
                                    );


                        // 1、深入数据对象
                                /*
                                    有一点要注意： 正如 v-bind:class 和 v-bind:style 这样的指令在模板与语法中被特别对待一样，
                                    它们在VNode数据对象中也有对应的顶层字段。该对象也允许你绑定普通的HMTL attribute(标签属性)，
                                    也许绑定如 innerHTML 这样的DOM property (这会覆盖v-html指令)
                                */

                                    // 数据对象
                                    {
                                            // 与 'v-bind:class' 的API相同，接受一个字符串、对象 或者对象组成的数组
                                            class:{
                                                foo:true,
                                                bar:false
                                            },

                                            // 与 'v-bind:style'的API相同，接受一个对象、数组，或对象数组
                                            style:{
                                                color:'red',
                                                fontSize:'14px'
                                            },

                                            //  普通的HTML attribure(标签属性)
                                            attrs:{
                                                id:'foo'
                                            },

                                            // 组件 prop
                                            props:{
                                                myProp:'bar'
                                            },

                                            // DOM property(DOM 属性)
                                            domProps:{
                                                innerHTML:'baz'
                                            },

                                            /*
                                                事件监听器
                                                在 'on' 内。
                                                但不再支持如 'v-on:keyup.enter'这样的修饰符。
                                                需要在处理函数中手动检查keyCode.
                                            */ 
                                            on:{
                                                click:this.nativeClickHandler
                                            },

                                            /*
                                                自定义指令。
                                                注意： 你无法对 'binding'钩子函数中的 oldValue参数进行赋值，因为Vue已经自动为你进行了同步！
                                            */ 
                                            directives:[
                                                {
                                                    name:'my-coustom-directive',
                                                    value:'2',
                                                    experession:'1+1',
                                                    arg:'foo',
                                                    modifiers:{
                                                        bar:true
                                                    }
                                                }
                                            ],

                                            /*
                                                作用域插槽
                                                格式为：  {name: props=> createElement('span',props.text)}
                                            */
                                            scopedSlots:{
                                                default:props=> createElement('span',props.text)
                                            },

                                            // 如果组件是其他组件的子组件，需为插槽指定名称
                                            slot:'name-of-slot',

                                            // 其他特殊顶层属性
                                            key:'myKey',
                                            ref:'myRef',
                                            /*
                                                如果你在渲染函数中给多个元素都应用了相同的 ref 名
                                                那么 '$refs.myRef'  会变成一个数组
                                            */ 

                                            refInFor:true
                                    }
                        
                    // 2、完整示例
                                // 有了这些知识，我们现在可以完成我们最开始响实现的组件
                                 
                                var getChildrenTextContent = funciton(children){
                                    return children.map(function(node){
                                        return node.children? getChildrenTextContent(node.children):node.text
                                    }).join('')
                                }

                                Vue.component('anchored-heading',{
                                    render:function(createElement){
                                        // 创建 kebab-case 风格的ID
                                        var headingId = getChildrenTextContent(this.$slots.default)
                                            .toLowerCase()
                                            .replace(/\W+/g, '-')
                                            .replace(/(^-|-$)/g, '')

                                        return createElement(
                                            'h'+this.level, // 元素标签名称
                                            [
                                                createElement('a',{
                                                    attrs:{
                                                        name:headingId,
                                                        href:'#'+headingId
                                                    }
                                                },this.$slots.default)
                                            ]
                                        )
                                    },
                                    // 组件属性声明
                                    props:{
                                        level:{
                                            type:Number,
                                            required:true
                                        }
                                    }
                                });


                    // 3、约束
                                // VNode 必须唯一
                                // 组件树中的所有VNode必须是唯一的。这意味着，下面的渲染函数是不合法的：
                                        render:function(createElement){
                                            var  myParagraphVNode = createElement('p','hi');
                                            return createElement('div',[
                                                // 错误-重复的 VNode
                                                myParagraphVNode,myParagraphVNode
                                            ])
                                        }
                                /*
                                    如果你真的需要重复很多次的元素/组件,你可以使用工厂函数来实现。

                                    例如，下面这渲染函数用完全合法的方式渲染了20个相同的段落：
                                */ 
                                       render:function(createElement){
                                           return createElement('div',
                                            Array.apply(null,{length:20}).map(function(){
                                                return createElement('p','hi')
                                            })
                                           )
                                       }


        </script>
    </body>
</html>